package com.lt.schoolchat.controller;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.lt.schoolchat.common.BaseResponse;
import com.lt.schoolchat.common.DeleteRequest;
import com.lt.schoolchat.common.ErrorCode;
import com.lt.schoolchat.common.ResultUtils;
import com.lt.schoolchat.exception.BusinessException;
import com.lt.schoolchat.model.dto.user.*;
import com.lt.schoolchat.model.entity.User;
import com.lt.schoolchat.model.vo.UserVO;
import com.lt.schoolchat.service.UserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.DigestUtils;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.lt.schoolchat.constant.UserConstant.SALT;

/**
 * 用户接口
 *
 * @author teng
 */
@RestController
@RequestMapping("/user")
@Api(tags = "用户接口")
@Slf4j
public class UserController {
    @Resource
    private UserService userService;
    private final ExecutorService ioExecutorService = new ThreadPoolExecutor(4, 20, 10, TimeUnit.MINUTES,
            new ArrayBlockingQueue<>(10000));


    @PostMapping("/register")
    @ApiOperation("用户注册")
    public BaseResponse<Long> userRegister(@RequestBody UserRegisterRequest userRegisterRequest) {
        if (userRegisterRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String userAccount = userRegisterRequest.getUserAccount();
        String userPassword = userRegisterRequest.getUserPassword();
        String checkPassword = userRegisterRequest.getCheckPassword();
        if (StringUtils.isAnyBlank(userAccount, userPassword, checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号或密码不能为空");
        }
        long result = userService.userRegister(userAccount, userPassword, checkPassword);
        return ResultUtils.success(result);
    }

    @PostMapping("/verify")
    @ApiOperation("用户实名认证")
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> userVerify(@RequestBody UserVerifiedRequest userVerifiedRequest) {
//        if (userVerifiedRequest == null) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR);
//        }
//        String userName = userVerifiedRequest.getUserName();
//        String idNumber = userVerifiedRequest.getIdNumber();
//        String phoneNo = userVerifiedRequest.getPhoneNo();
//        if (StringUtils.isBlank(userName)) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR, "真实姓名不能为空");
//        }
//        if (StringUtils.isBlank(idNumber)) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR, "身份证号不能为空");
//        }
//        if (StringUtils.isBlank(phoneNo)) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR, "手机号不能为空");
//        }
//        String frontImg = userVerifiedRequest.getFrontImg();
//        String backImg = userVerifiedRequest.getBackImg();
//        if (StringUtils.isAnyBlank(frontImg, backImg)) {
//            throw new BusinessException(ErrorCode.PARAMS_ERROR, "身份证照片不能为空");
//        }
//        CompletableFuture<Map<String, Object>> idCardFrontOcrFuture =
//                CompletableFuture.supplyAsync(() -> IdCardOcrUtils.checkIdCard(frontImg, "0"), ioExecutorService);
//        CompletableFuture<Map<String, Object>> idCardOcrBackFuture =
//                CompletableFuture.supplyAsync(() -> IdCardOcrUtils.checkIdCard(backImg, "1"), ioExecutorService);
//        Map<String, Object> frontMap = idCardFrontOcrFuture.join();
//        Map<String, Object> backMap = idCardOcrBackFuture.join();
//        Boolean isExpire = (Boolean) backMap.get("isExpire");
//        if (isExpire) {
//            throw new BusinessException(ErrorCode.OPERATION_ERROR, "身份证已经过期！");
//        }
//        String ocrUserName = (String) frontMap.get("userName");
//        String ocrIdNumber = (String) frontMap.get("idNumber");
//        if (!userName.equals(ocrUserName)) {
//            throw new BusinessException(ErrorCode.OPERATION_ERROR, "填写真实姓名与身份证真实姓名不同！");
//        }
//        if (!idNumber.equals(ocrIdNumber)) {
//            throw new BusinessException(ErrorCode.OPERATION_ERROR, "填写身份证号与身份证真实身份证号不同！");
//        }
//        PhoneNameIdCardUtils.checkInfo(userName, idNumber, phoneNo);
        Map<String, Object> map = new HashMap<>();
        map.put("success", true);
        map.put("code", 400100);
        map.put("message", "成功");
        return map;
    }

    /**
     * 用户登录
     */
    @PostMapping("/login")
    public BaseResponse<User> userLogin(@RequestBody UserLoginRequest userLoginRequest, HttpServletRequest request) {
        if (userLoginRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String userAccount = userLoginRequest.getUserAccount();
        String userPassword = userLoginRequest.getUserPassword();
        if (StringUtils.isAnyBlank(userAccount, userPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户账号或密码不能为空");
        }
        User user = userService.userLogin(userAccount, userPassword, request);
        return ResultUtils.success(user);
    }

    @PostMapping("/logout")
    @ApiOperation("用户注销")
    public BaseResponse<Boolean> userLogout(HttpServletRequest request) {
        if (request == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean result = userService.userLogout(request);
        return ResultUtils.success(result);
    }

    @GetMapping("/get/login")
    @ApiOperation("获取当前登录用户")
    public BaseResponse<UserVO> getLoginUser(HttpServletRequest request) {
        User user = userService.getLoginUser(request);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return ResultUtils.success(userVO);
    }

    @PostMapping("/updatePwd")
    @ApiOperation("修改密码")
    public BaseResponse<Boolean> updatePwd(@RequestBody UserPwdUpdateRequest userPwdUpdateRequest, HttpServletRequest request) {
        User loginUser = userService.getLoginUser(request);
        if (loginUser == null) {
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        String userPassword = userPwdUpdateRequest.getUserPassword();
        String newPassword = userPwdUpdateRequest.getNewPassword();
        String checkPassword = userPwdUpdateRequest.getCheckPassword();
        if (StringUtils.isAnyBlank(userPassword, newPassword, checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "密码不能为空");
        }
        String dbPassword = loginUser.getUserPassword();
        // 原始密码加密后的密码
        String encryptPwd = DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes());
        if (!dbPassword.equals(encryptPwd)) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "原始密码错误");
        }
        if (newPassword.length() < 8 || checkPassword.length() < 8) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "用户密码过短");
        }
        // 密码和校验密码相同
        if (!newPassword.equals(checkPassword)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "两次输入的密码不一致");
        }
        // 更新密码
        encryptPwd = DigestUtils.md5DigestAsHex((SALT + newPassword).getBytes());
        loginUser.setUserPassword(encryptPwd);
        boolean flag = userService.updateById(loginUser);
        if (flag) {
            return ResultUtils.success(true);
        }
        return ResultUtils.error(ErrorCode.OPERATION_ERROR, "更新失败");
    }

    /**
     * 创建用户
     */
    @PostMapping("/add")
    public BaseResponse<Long> addUser(@RequestBody UserAddRequest userAddRequest) {
        if (userAddRequest == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String userAccount = userAddRequest.getUserAccount();
        String userName = userAddRequest.getUserName();
        String userPassword = userAddRequest.getUserPassword();
        Integer gender = userAddRequest.getGender();
        String userAvatar = userAddRequest.getUserAvatar();
        if (StringUtils.isAnyBlank(userAccount, userName, userPassword, userAvatar)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        if (gender == null || (gender != 0 && gender != 1)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = new User();
        BeanUtils.copyProperties(userAddRequest, user);
        user.setUserPassword(DigestUtils.md5DigestAsHex((SALT + userPassword).getBytes()));
        boolean result = userService.save(user);
        if (!result) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR);
        }
        return ResultUtils.success(user.getId());
    }

    /**
     * 删除用户
     */
    @PostMapping("/delete")
    public BaseResponse<Boolean> deleteUser(@RequestBody DeleteRequest deleteRequest) {
        if (deleteRequest == null || deleteRequest.getId() <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        boolean b = userService.removeById(deleteRequest.getId());
        return ResultUtils.success(b);
    }

    /**
     * 更新用户
     */
    @PostMapping("/update")
    public BaseResponse<Boolean> updateUser(@RequestBody UserUpdateRequest userUpdateRequest) {
        if (userUpdateRequest == null || userUpdateRequest.getId() == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        String userName = userUpdateRequest.getUserName();
        String userAccount = userUpdateRequest.getUserAccount();
        String userAvatar = userUpdateRequest.getUserAvatar();
        Integer gender = userUpdateRequest.getGender();
        String userPassword = userUpdateRequest.getUserPassword();
        if (StringUtils.isAnyBlank(userAccount, userName, userPassword, userAvatar)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        if (gender == null || (gender != 0 && gender != 1)) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = new User();
        BeanUtils.copyProperties(userUpdateRequest, user);
        boolean result = userService.updateById(user);
        return ResultUtils.success(result);
    }

    /**
     * 根据 id 获取用户
     */
    @GetMapping("/get")
    public BaseResponse<UserVO> getUserById(int id) {
        if (id <= 0) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        User user = userService.getById(id);
        UserVO userVO = new UserVO();
        BeanUtils.copyProperties(user, userVO);
        return ResultUtils.success(userVO);
    }

    /**
     * 获取用户列表
     */
    @GetMapping("/list")
    public BaseResponse<List<UserVO>> listUser(UserQueryRequest userQueryRequest) {
        User userQuery = new User();
        if (userQueryRequest != null) {
            BeanUtils.copyProperties(userQueryRequest, userQuery);
        }
        QueryWrapper<User> queryWrapper = new QueryWrapper<>(userQuery);
        List<User> userList = userService.list(queryWrapper);
        List<UserVO> userVOList = userList.stream().map(user -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            return userVO;
        }).collect(Collectors.toList());
        return ResultUtils.success(userVOList);
    }

    /**
     * 分页获取用户列表
     */
    @GetMapping("/list/page")
    public BaseResponse<Page<UserVO>> listUserByPage(UserQueryRequest userQueryRequest) {
        long current = 1;
        long size = 10;
        User userQuery = new User();
        if (userQueryRequest != null) {
            BeanUtils.copyProperties(userQueryRequest, userQuery);
            current = userQueryRequest.getCurrent();
            size = userQueryRequest.getPageSize();
        }
        String userName = userQueryRequest.getUserName();
        String userAccount = userQueryRequest.getUserAccount();
        String userRole = userQueryRequest.getUserRole();
        Integer gender = userQueryRequest.getGender();
        Date createTime = userQueryRequest.getCreateTime();
        Date updateTime = userQueryRequest.getUpdateTime();
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.like(StringUtils.isNoneBlank(userName), "userName", userName);
        queryWrapper.like(StringUtils.isNoneBlank(userAccount), "userAccount", userAccount);
        queryWrapper.eq(StringUtils.isNoneBlank(userRole), "userRole", userRole);
        queryWrapper.eq(gender != null, "gender", gender);
        queryWrapper.ge(createTime != null, "createTime", createTime);
        queryWrapper.ge(updateTime != null, "updateTime", updateTime);
        Page<User> userPage = userService.page(new Page<>(current, size), queryWrapper);
        Page<UserVO> userVOPage = new PageDTO<>(userPage.getCurrent(), userPage.getSize(), userPage.getTotal());
        List<UserVO> userVOList = userPage.getRecords().stream().map(user -> {
            UserVO userVO = new UserVO();
            BeanUtils.copyProperties(user, userVO);
            return userVO;
        }).collect(Collectors.toList());
        userVOPage.setRecords(userVOList);
        return ResultUtils.success(userVOPage);
    }
}
